﻿using System;
using System.IO;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using System.Reflection;
using System.Xml.Serialization;

using DevExpress.Web.ASPxTreeList;
using DevExpress.Web.ASPxGridView;
using OT.Common;
using System.Text.RegularExpressions;
using System.Drawing;
using DevExpress.Web.Data;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using DevExpress.Xpo;
using System.ComponentModel;
using DevExpress.Web.ASPxClasses;

namespace OT.Dev
{
    public class DevPage : System.Web.UI.Page
    {
        public DevPage()
        {
        }

        #region DefaultPageSize

        protected int DefaultPageSize
        {
            get
            {
                // TODO:这里应当从配置中获得页面默认行数
                return 15;
            }
        }

        #endregion

        /***
         *  Page Event
         */

        #region Page_Init

        virtual protected void Page_Init(object sender, EventArgs e)
        {
            XpoSession = new DevExpress.Xpo.Session();
        }
        #endregion

        #region Dispose

        public override void Dispose()
        {
            XpoSession.Dispose();
            base.Dispose();
        }

        #endregion

        /***
         *  Session
         */

        #region XpoSession

        Session _xpoSession;

        public Session XpoSession
        {
            get { return _xpoSession; }
            set { _xpoSession = value; }
        }
        
        #endregion

        /***
         *  TreeList
         */

        #region GetIconUrl

        protected string GetIconUrl(TreeListDataCellTemplateContainer container)
        {
            return string.Format("~/Images/{0}.gif", container.GetValue("IconName"));
        }

        #endregion

        #region GetTreeFocusKey

        protected string GetTreeFocusKey(ASPxTreeList tree)
        {
            string key = null;
            try
            {
                key = tree.FocusedNode.Key;
            }
            catch (NullReferenceException ex)
            {
                // TODO:使用日志记录异常
            }

            return key;
        }

        #endregion

        #region GridRowActive

        protected void GridRowActive(ASPxTreeList tree, ASPxGridView grid)
        {
            int rowIndex = grid.FindVisibleIndexByKeyValue(tree.FocusedNode.Key);
            if (rowIndex >= 0)
            {
                grid.FocusedRowIndex = rowIndex;
                grid.PageIndex = (int)(rowIndex / grid.SettingsPager.PageSize);
            }
        }

        #endregion

        /***
         *  GridView
         */

        #region HandleDefaultEvent

        /// <summary>
        /// 处理通用事件
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="grid"></param>
        /// <returns></returns>
        protected bool HandleDefaultEvent( string arg , ASPxGridView grid , IObjectBLL bll)
        {
            bool bHandle = false;
            if (arg.Equals(GEvent.New))
            {
                grid.AddNewRow();
                bHandle = true;
            }
            else if (arg.StartsWith(GEvent.PagerStyle))
            {
                GridPagerStyleSetting(grid, arg);
                bHandle = true;
            }
            else if (arg.Equals(GEvent.FilterRowOpen))
            {
                grid.Settings.ShowFilterRow = true;
                grid.Settings.ShowFilterRowMenu = true;
                bHandle = true;
            }
            else if (arg.Equals(GEvent.Delete))
            {
                GroupDelete(grid, bll);
                grid.DataBind();
                grid.Selection.UnselectAll();
                bHandle = true;
            }
            else if (arg.Equals(GEvent.DetailExportMode))
            {
                DetailExportModeSetting(grid, arg);
                bHandle = true;
            }

            return bHandle;
        }

        #endregion

        #region AutoSettingGridColumnStyle

        // 对表格的列进行自动设置
        protected void AutoSettingGridColumnStyle(ASPxGridView grid)
        {
            // 首先遍历列，获取表格整体效果
            // 1、获得各列对应的字段
            // 2、获得总的列数
            List<ColumnItem> items = new List<ColumnItem>();
            foreach (GridViewColumn column in grid.Columns)
            {
                // 跳过不可见列
                if (!column.Visible)
                    continue;

                // 设置标题不换行
                GridColumnUtility.SetCaptionNowrap(column);

                ColumnItem item = new ColumnItem();
                GridColumnUtility.GetColumnInfo(column , item);
                items.Add(item);
            }

            // 再次遍历列，根据字段定义自动调整列宽
            foreach (GridViewColumn column in grid.Columns)
            {
                // 调整算法
                // 1、跳过不可见列
                // 2、命令列根据可见命令文本字数指定宽度
                // 3、
            }
        }

        #endregion

        #region GroupDelete

        protected void GroupDelete(ASPxGridView grid, IObjectBLL bll)
        {
            // 成组的删除记录
            List<object> objs = grid.GetSelectedFieldValues(grid.KeyFieldName);
            bool canDel = true;
            string error = "";

            List<string> ids = new List<string>();
            foreach (object obj in objs)
            {
                ids.Add(obj.ToString());
                if (!bll._CheckDelete(obj.ToString(), ref error))
                {
                    canDel = false;
                    break;
                }
            }

            if (canDel)
                bll._DeleteByKeys(ids);
            else
                throw new ApplicationException(error);
        }

        #endregion

        #region DataSourceRefreshCancel

        protected void DataSourceRefreshCancel(ASPxGridView grid, CancelEventArgs e)
        {
            // 取消原定修改
            e.Cancel = true;
            grid.CancelEdit();

            // 更新数据
            grid.DataBind();
        }

        #endregion

        /***
         *  Style
         */

        #region InitTreeStyle

        protected void InitTreeStyle(ASPxTreeList tree)
        {
            // Settings
            tree.Settings.ShowColumnHeaders = false;

            tree.SettingsBehavior.AllowFocusedNode = true;
            tree.SettingsBehavior.DisablePartialUpdate = true;
            tree.SettingsBehavior.AllowDragDrop = false;
            tree.SettingsBehavior.AllowSort = false;

            tree.SettingsLoadingPanel.Text = "加载中&hellip;";

            // Layout
            tree.Height = Unit.Percentage(100);
            tree.Width = Unit.Percentage(100);
            tree.AutoGenerateColumns = false;
            tree.Border.BorderWidth = Unit.Pixel(0);

            // Style
       //   tree.Styles.Indent.BackColor = Color.Transparent;
            tree.Styles.Indent.BackColor = Color.Transparent;
            tree.Styles.IndentWithButton.BackColor = Color.Transparent;
            tree.Styles.Node.BackColor = Color.Transparent;
            tree.Styles.Cell.Paddings.PaddingLeft = Unit.Pixel(1);
        }

        #endregion

        #region InitGridStyle

        protected void InitGridStyle(ASPxGridView grid, string cookieId )
        {
            grid.Width = Unit.Percentage(99);
            grid.AutoGenerateColumns = false;
            // 列工具箱
            grid.SettingsCustomizationWindow.Enabled = true;
            grid.SettingsDetail.ExportMode = GridViewDetailExportMode.All;

            // 分组栏
            grid.Settings.ShowGroupPanel = false ;
            grid.SettingsEditing.EditFormColumnCount = 1 ;
            grid.SettingsEditing.Mode = GridViewEditingMode.PopupEditForm;
            grid.SettingsEditing.PopupEditFormWidth = Unit.Pixel(500);
            grid.SettingsEditing.PopupEditFormHorizontalAlign = PopupHorizontalAlign.Center;

            // 响应
            grid.SettingsBehavior.ConfirmDelete = true;
            grid.SettingsBehavior.ColumnResizeMode = ColumnResizeMode.NextColumn;
            grid.SettingsBehavior.AllowFocusedRow = true ;
            grid.SettingsBehavior.AllowMultiSelection = true ;
            // 分页
            grid.SettingsPager.AlwaysShowPager = true;
            grid.SettingsPager.Position = PagerPosition.Bottom;
            grid.SettingsPager.PageSize = DefaultPageSize;
            grid.SettingsPager.Summary.AllPagesText = "当前第 {0}页,共 {1}页 (记录数:{2})" ;
            grid.SettingsPager.Summary.Text = "当前第 {0}页,共 {1}页 (记录数:{2})" ;

            // 间隔行
            grid.Styles.AlternatingRow.Enabled = DevExpress.Web.ASPxClasses.DefaultBoolean.True;
            // grid.Styles.AlternatingRow.HoverStyle.BackColor = Color.Crimson;
            // grid.Styles.AlternatingRow.BackColor = Color.Crimson;

            // Filter
            grid.Settings.ShowHeaderFilterButton = false;
            grid.Settings.ShowFilterBar = GridViewStatusBarMode.Hidden;

            /***        Cookie设置 
             * 
             * 开启Cookie后用户在任一页面上进行的列宽、列位置、过滤设置、分组和排序、页选择都会被记录
             * 为用户实现表格展示的个性化
             * 
             */
            grid.SettingsCookies.Enabled = true;
            grid.SettingsCookies.CookiesID = cookieId;

            /***        提示设置
             * 
             * 设定列表控件的中文提示
             * 
             */
            // TODO:这里的文字信息应当放入配置文件
            grid.SettingsText.CommandClearFilter = "清除过滤条件";
            grid.SettingsText.CommandEdit = "修改";
            grid.SettingsText.CommandSelect = "选择";
            grid.SettingsText.CommandCancel = "取消";
            grid.SettingsText.CommandNew = "新增";
            grid.SettingsText.CommandUpdate = "更新";
            grid.SettingsText.CommandDelete = "删除";
            grid.SettingsText.ConfirmDelete = "是否确认删除?";
            grid.SettingsText.EmptyDataRow = "无数据显示";
            grid.SettingsText.CustomizationWindowCaption = "列工具箱";
            grid.SettingsText.GroupPanel = "将列头拖到这里按该列分组；使用鼠标可改变列宽度，调整列显示顺序；点击列头可进行排序(Shift+点击：多列排序)。";
            grid.SettingsText.EmptyHeaders = "将列工具箱中的列拖到这里显示";
            grid.SettingsText.GroupContinuedOnNextPage = "分组延续到下一页";
            grid.SettingsText.PopupEditFormCaption = "数据维护";
            grid.SettingsText.Title = "";
            grid.SettingsText.FilterBarClear = "清除";
            grid.SettingsText.FilterBarCreateFilter = "高级查询";
            grid.SettingsText.FilterControlPopupCaption = "高级查询";
            grid.SettingsText.HeaderFilterShowAll = "全部显示";

            grid.SettingsLoadingPanel.Text = "加载中&hellip;";

        }

        #endregion

        #region GridPagerStyleSetting

        protected void GridPagerStyleSetting(ASPxGridView grid, PagerStyle style)
        {
            switch (style)
            {
                case PagerStyle.Pager:
                    grid.SettingsPager.Visible = true;
                    grid.SettingsPager.AlwaysShowPager = true;
                    grid.SettingsPager.Mode = GridViewPagerMode.ShowPager;
                    grid.SettingsPager.PageSize = DefaultPageSize;
                    grid.Settings.ShowVerticalScrollBar = false;
                    break;
                case PagerStyle.NonPager:
                    grid.SettingsPager.Visible = false;
                    grid.SettingsPager.Mode = GridViewPagerMode.ShowAllRecords;
                    grid.Settings.ShowVerticalScrollBar = false;
                    grid.DataBind();
                    break;
                case PagerStyle.NonPagerWithFreezing:
                    grid.SettingsPager.Visible = false;
                    grid.SettingsPager.Mode = GridViewPagerMode.ShowAllRecords;
                    grid.Settings.ShowVerticalScrollBar = true;
                    grid.Settings.VerticalScrollableHeight = 430;
                    grid.DataBind();
                    break;
            }
        }

        protected void GridPagerStyleSetting(ASPxGridView grid, string param)
        {
            // 分解param获得枚举值
            Regex regex = new Regex("^PagerStyle{(?<mode>[^}]+)}$", RegexOptions.IgnoreCase);
            Match m = regex.Match(param);

            // 转换为枚举
            PagerStyle style = EnumUtility.GetEnumValue<PagerStyle>(m.Groups["mode"].Value);

            GridPagerStyleSetting(grid, style);
        }

        #endregion

        #region DetailExportModeSetting

        protected void DetailExportModeSetting(ASPxGridView grid, string param)
        {
            // 分解param获得枚举值
            Regex regex = new Regex("^ExportMode{(?<mode>[^}]+)}$", RegexOptions.IgnoreCase);
            Match m = regex.Match(param);

            // 转换为枚举
            DetailExportMode mode = EnumUtility.GetEnumValue<DetailExportMode>(m.Groups["mode"].Value);

            DetailExportModeSetting(grid, mode);
        }

        protected void DetailExportModeSetting(ASPxGridView grid, DetailExportMode mode)
        {
            switch (mode)
            {
                case DetailExportMode.All:
                    grid.SettingsDetail.ExportMode = GridViewDetailExportMode.All;
                    break;
                case DetailExportMode.Expanded:
                    grid.SettingsDetail.ExportMode = GridViewDetailExportMode.Expanded;
                    break;
                case DetailExportMode.None :
                    grid.SettingsDetail.ExportMode = GridViewDetailExportMode.None;
                    break;
            }
        }

        #endregion

        /***
         *  GetValue
         */

        #region GetEventArgsValues

        protected void GetEventArgsValues(object obj, System.Collections.Specialized.OrderedDictionary dict)
        {
            // 反射获得对象特性DatabaseColumn的定义

            PropertyInfo[] props = obj.GetType().GetProperties();

            foreach (PropertyInfo pInfo in props)
            {
                object[] attrs = pInfo.GetCustomAttributes(false);
                // 根据定义的DatabaseColumn从字典中获取值

                bool need = false;
                foreach (object attr in attrs)
                {
                    if (attr is OT.ORM.DatabaseColumnAttribute)
                    {
                        need = true;
                        break;
                    }
                }
                // 尝试从字典中获得值

                if (need)
                {
                    if (dict.Contains(pInfo.Name))
                    {
                        pInfo.SetValue(obj, dict[pInfo.Name], null);
                    }
                }
            }
        }

        #endregion

        /***
         *  Error
         */

        #region AttachError

        /// <summary>
        /// 将错误信息附加到每一列上
        /// </summary>
        /// <param name="errors"></param>
        /// <param name="columnName"></param>
        /// <param name="errorText"></param>
        /// <returns></returns>
        protected string AttachError(ASPxGridView grid, Dictionary<GridViewColumn, string> errors, string columnName, string errorText)
        {
            if (errors != null)
            {
                GridViewColumn column = grid.Columns[columnName];

                if (errors.ContainsKey(column))
                {
                    errors[column] = errors[column] + errorText;
                }
                else
                    errors[column] = errorText;
            }

            return errorText;
        }

        #endregion

        /***
         *  Export
         */

        #region Export

        protected void Export(DevExpress.Web.ASPxGridView.Export.ASPxGridViewExporter exporter, ExportFileType exportFileType)
        {
            //ExportFileType type = EnumUtility.GetEnumValue<ExportFileType>(exportFileType);

            switch (exportFileType)
            {
                case ExportFileType.XLS:
                    exporter.WriteXlsToResponse(true);
                    break;
                case ExportFileType.PDF:
                    exporter.WritePdfToResponse(true);
                    break;
                case ExportFileType.RTF:
                    exporter.WriteRtfToResponse(true);
                    break;
                case ExportFileType.CSV:
                    exporter.WriteCsvToResponse(true);
                    break;
            }
        }

        #endregion

        /***
         *  Validation
         */

        #region ValidationMDL

        protected void ValidationMDL<T>(T t, ASPxGridView grid, ASPxDataValidationEventArgs e)
        {
            ValidationResults rs = Validation.Validate<T>(t);
            if (!rs.IsValid)
            {
                string error = "";
                string div = "";
                foreach (ValidationResult result in rs)
                {
                    error += div + result.Message;
                    div = ";";
                    AttachError(grid, e.Errors, result.Key, result.Message);
                }
                e.RowError = error;
            }

        }
        #endregion


    }


}
